package aspect;

import annotation.Transaction;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import tx.TransactionManager;

import java.lang.reflect.Method;

//将切面类交个spring管理
@Component
//告诉spring我是一个切面类
@Aspect
public class TxAspect {

    @Autowired
    private TransactionManager tx;

//    切入点规则
    @Pointcut("execution(* service..*.*(..))")
    public void pointcut(){

    }

    //通知的方法：环绕通知
//    @Around("execution(* service..*.*(..))"/*+"&& @annotation(trans)"*/)
//                          AOP注解            自定义注解
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint/*, Transaction trans*/) throws Throwable {

        //在方法执行之前开启事务

        tx.open1();

        //执行本职操作

         Object target=joinPoint.proceed();

        //告诉事务模块进行事务提交

        tx.commit();
        return target;
    }



//    前置通知：主要用在  日志分析  日志监控
//    前置通知：没有执行  目标方法
//    jionPoint主要用于在非环绕通知中
     @Before("pointcut()")
    public void before(JoinPoint joinPoint){
        System.out.println("前置通知已执行");
//        如何获取连接点的方法  方法名为addUser
//        1.获取目标对象的类型
        Class targetClass=joinPoint.getTarget().getClass();
        System.out.println(targetClass);

//        2.获取该类中的方法签名对象
        MethodSignature methodSignature= (MethodSignature) joinPoint.getSignature();

//        3.获取方法名：
        String methodName=methodSignature.getName();
        System.out.println(methodName);
    }



//    后置通知：
//    建议返回值类型与 环绕通知 一致
    @AfterReturning(value = "pointcut()",returning = "number")
    public void afterReturning(int number){
        System.out.println("后置通知");
        System.out.println(number);
    }

//    异常通知
    @AfterThrowing(value = "pointcut()",throwing ="throwable" )
    public void afterThrowing(Throwable throwable){
        System.out.println("异常通知");
        System.out.println("异常信息"+throwable.getMessage());
    }

//最终通知
    public void after(){
        System.out.println("最终降临");
    }



}









